package billing

import (
	"context"
	"fmt"
	"log"
	"net"
	"time"
)

// ========================================
// 计费系统测试/演示代码
// 用于快速验证计费功能
// ========================================

// DemoTrafficQuotaCheck 演示流量配额检查
func DemoTrafficQuotaCheck() {
	fmt.Println("\n========================================")
	fmt.Println("演示1: 流量配额检查")
	fmt.Println("========================================")

	// 创建计费管理器
	manager := NewBillingManager()
	manager.Enable()

	// 设置测试用户：1GB流量配额
	userID := "demo-user-001"
	manager.SetUserQuota(userID, 1, PaymentTypeCashier,
		"https://pay.example.com/checkout?user="+userID, "ORDER-TRAFFIC-001")

	// 模拟10次请求，每次100MB
	for i := 1; i <= 10; i++ {
		ctx := &InterceptContext{
			Ctx:         context.Background(),
			TunnelID:    "tunnel-demo-001",
			UserID:      userID,
			RequestID:   fmt.Sprintf("req-%03d", i),
			Protocol:    "HTTP",
			RequestSize: 100 * 1024 * 1024, // 100MB
			HTTPMethod:  "GET",
			HTTPPath:    "/demo",
			HTTPHeaders: map[string]string{"accept": "text/html"},
			AcceptHTML:  true,
		}

		allowed, response, err := manager.CheckRequest(ctx)
		if err != nil {
			log.Printf("❌ 请求#%d 检查失败: %v", i, err)
			continue
		}

		if allowed {
			log.Printf("✅ 请求#%d 已放行", i)
		} else {
			log.Printf("🚫 请求#%d 被拦截 (流量配额用尽)", i)
			fmt.Printf("\n付费响应预览:\n%s\n", string(response[:min(500, len(response))]))
			break
		}
	}
}

// DemoBandwidthLimit 演示带宽限制
func DemoBandwidthLimit() {
	fmt.Println("\n========================================")
	fmt.Println("演示2: 带宽限制")
	fmt.Println("========================================")

	manager := NewBillingManager()
	manager.Enable()

	// 设置测试用户：10MB/s带宽
	userID := "demo-user-002"
	manager.SetUserBandwidth(userID, 10, PaymentTypeQRCode,
		"https://pay.example.com/qrcode?user="+userID, "ORDER-BANDWIDTH-001")

	// 模拟快速发送大量请求
	for i := 1; i <= 20; i++ {
		ctx := &InterceptContext{
			Ctx:           context.Background(),
			TunnelID:      "tunnel-demo-002",
			UserID:        userID,
			RequestID:     fmt.Sprintf("req-%03d", i),
			Protocol:      "HTTP",
			RequestSize:   5 * 1024 * 1024, // 5MB
			HTTPMethod:    "GET",
			HTTPPath:      "/large-file",
			HTTPHeaders:   map[string]string{"accept": "application/json"},
			IsJSONRequest: false,
			AcceptHTML:    false,
		}

		allowed, response, err := manager.CheckRequest(ctx)
		if err != nil {
			log.Printf("❌ 请求#%d 检查失败: %v", i, err)
			continue
		}

		if allowed {
			log.Printf("✅ 请求#%d 已放行", i)
		} else {
			log.Printf("🚫 请求#%d 被拦截 (带宽限制)", i)
			fmt.Printf("\n付费响应预览 (JSON):\n%s\n", string(response))
			break
		}

		// 模拟间隔
		time.Sleep(50 * time.Millisecond)
	}
}

// DemoHTMLResponse 演示HTML付费页面
func DemoHTMLResponse() {
	fmt.Println("\n========================================")
	fmt.Println("演示3: HTML付费页面生成")
	fmt.Println("========================================")

	manager := NewBillingManager()
	manager.Enable()

	// 设置配额为0（立即触发拦截）
	userID := "demo-user-003"
	manager.SetUserQuota(userID, 0, PaymentTypeCashier,
		"https://pay.example.com/checkout?order=ORDER-HTML-001", "ORDER-HTML-001")

	ctx := &InterceptContext{
		Ctx:         context.Background(),
		TunnelID:    "tunnel-demo-003-very-long-tunnel-id-for-testing",
		UserID:      userID,
		RequestID:   "req-html-001",
		Protocol:    "HTTP",
		RequestSize: 1024,
		HTTPMethod:  "GET",
		HTTPPath:    "/",
		HTTPHeaders: map[string]string{
			"accept":       "text/html",
			"content-type": "text/html",
		},
		AcceptHTML: true,
	}

	allowed, response, err := manager.CheckRequest(ctx)
	if err != nil {
		log.Printf("❌ 检查失败: %v", err)
		return
	}

	if !allowed {
		fmt.Println("\nHTML页面预览（前1000字符）:")
		fmt.Println("----------------------------------------")
		preview := string(response[:min(1000, len(response))])
		fmt.Println(preview)
		fmt.Println("----------------------------------------")
		fmt.Printf("\n完整页面长度: %d 字节\n", len(response))
	}
}

// DemoJSONResponse 演示JSON付费响应
func DemoJSONResponse() {
	fmt.Println("\n========================================")
	fmt.Println("演示4: JSON付费响应生成")
	fmt.Println("========================================")

	manager := NewBillingManager()
	manager.Enable()

	// 设置配额为0（立即触发拦截）
	userID := "demo-user-004"
	manager.SetUserQuota(userID, 0, PaymentTypeQRCode,
		"https://pay.example.com/qrcode?order=ORDER-JSON-001", "ORDER-JSON-001")

	ctx := &InterceptContext{
		Ctx:         context.Background(),
		TunnelID:    "tunnel-demo-004",
		UserID:      userID,
		RequestID:   "req-json-001",
		Protocol:    "HTTP",
		RequestSize: 1024,
		HTTPMethod:  "POST",
		HTTPPath:    "/api/data",
		HTTPHeaders: map[string]string{
			"accept":       "application/json",
			"content-type": "application/json",
		},
		IsJSONRequest: true,
		AcceptHTML:    false,
	}

	allowed, response, err := manager.CheckRequest(ctx)
	if err != nil {
		log.Printf("❌ 检查失败: %v", err)
		return
	}

	if !allowed {
		fmt.Println("\nJSON响应:")
		fmt.Println("----------------------------------------")
		fmt.Println(string(response))
		fmt.Println("----------------------------------------")
	}
}

// DemoEnableDisable 演示启用/禁用功能
func DemoEnableDisable() {
	fmt.Println("\n========================================")
	fmt.Println("演示5: 启用/禁用计费系统")
	fmt.Println("========================================")

	manager := NewBillingManager()

	// 设置配额为0
	userID := "demo-user-005"
	manager.SetUserQuota(userID, 0, PaymentTypeCashier, "https://pay.example.com", "ORDER-TOGGLE")

	ctx := &InterceptContext{
		Ctx:         context.Background(),
		TunnelID:    "tunnel-demo-005",
		UserID:      userID,
		RequestID:   "req-toggle-001",
		Protocol:    "HTTP",
		RequestSize: 1024,
		AcceptHTML:  true,
	}

	// 测试1: 禁用状态（默认）
	fmt.Println("\n📌 测试1: 禁用状态")
	allowed, _, _ := manager.CheckRequest(ctx)
	if allowed {
		fmt.Println("✅ 请求放行（计费系统禁用）")
	}

	// 测试2: 启用状态
	fmt.Println("\n📌 测试2: 启用状态")
	manager.Enable()
	allowed, _, _ = manager.CheckRequest(ctx)
	if !allowed {
		fmt.Println("🚫 请求被拦截（计费系统启用）")
	}

	// 测试3: 再次禁用
	fmt.Println("\n📌 测试3: 再次禁用")
	manager.Disable()
	allowed, _, _ = manager.CheckRequest(ctx)
	if allowed {
		fmt.Println("✅ 请求放行（计费系统禁用）")
	}
}

// DemoTCPProtocol 演示TCP协议拦截
func DemoTCPProtocol() {
	fmt.Println("\n========================================")
	fmt.Println("演示6: TCP协议拦截（返回JSON）")
	fmt.Println("========================================")

	manager := NewBillingManager()
	manager.Enable()

	userID := "demo-user-006"
	manager.SetUserQuota(userID, 0, PaymentTypeQRCode, "https://pay.example.com/tcp", "ORDER-TCP-001")

	ctx := &InterceptContext{
		Ctx:         context.Background(),
		TunnelID:    "tunnel-demo-006",
		UserID:      userID,
		RequestID:   "req-tcp-001",
		Protocol:    "TCP", // TCP协议
		RequestSize: 1024,
	}

	allowed, response, err := manager.CheckRequest(ctx)
	if err != nil {
		log.Printf("❌ 检查失败: %v", err)
		return
	}

	if !allowed {
		fmt.Println("\nTCP协议拦截响应（JSON格式）:")
		fmt.Println("----------------------------------------")
		fmt.Println(string(response))
		fmt.Println("----------------------------------------")
		fmt.Println("\n💡 提示: TCP协议拦截时，客户端应显示付费信息在隧道列表中")
	}
}

// RunAllDemos 运行所有演示
func RunAllDemos() {
	fmt.Println("\n🎯 Internal Net Bridge - 计费系统演示")
	fmt.Println("=====================================")

	DemoTrafficQuotaCheck()
	time.Sleep(1 * time.Second)

	DemoBandwidthLimit()
	time.Sleep(1 * time.Second)

	DemoHTMLResponse()
	time.Sleep(1 * time.Second)

	DemoJSONResponse()
	time.Sleep(1 * time.Second)

	DemoEnableDisable()
	time.Sleep(1 * time.Second)

	DemoTCPProtocol()

	fmt.Println("\n✅ 所有演示完成!")
	fmt.Println("=====================================\n")
}

// DemoWithRealConnection 演示实际网络连接
func DemoWithRealConnection() {
	fmt.Println("\n========================================")
	fmt.Println("演示7: 实际网络连接测试")
	fmt.Println("========================================")

	manager := NewBillingManager()
	manager.Enable()

	// 设置配额为0
	userID := "demo-user-007"
	manager.SetUserQuota(userID, 0, PaymentTypeCashier,
		"https://pay.example.com/real", "ORDER-REAL-001")

	// 创建TCP监听器
	listener, err := net.Listen("tcp", "127.0.0.1:0")
	if err != nil {
		log.Printf("❌ 创建监听器失败: %v", err)
		return
	}
	defer listener.Close()

	fmt.Printf("📡 监听地址: %s\n", listener.Addr().String())
	fmt.Println("💡 使用 curl 或浏览器访问上述地址查看付费页面\n")

	// 等待连接
	go func() {
		for i := 0; i < 3; i++ { // 处理3个连接
			conn, err := listener.Accept()
			if err != nil {
				return
			}

			go func(c net.Conn) {
				defer c.Close()

				// 构建拦截上下文
				ctx := &InterceptContext{
					Ctx:         context.Background(),
					TunnelID:    "tunnel-real-007",
					UserID:      userID,
					RequestID:   fmt.Sprintf("req-real-%d", time.Now().Unix()),
					Protocol:    "HTTP",
					RemoteAddr:  c.RemoteAddr().String(),
					RequestSize: 1024,
					HTTPHeaders: map[string]string{"accept": "text/html"},
					AcceptHTML:  true,
				}

				// 执行计费检查
				allowed, response, err := manager.CheckRequest(ctx)
				if err != nil {
					log.Printf("❌ 检查失败: %v", err)
					return
				}

				if !allowed {
					// 发送付费页面
					httpResponse := fmt.Sprintf(
						"HTTP/1.1 402 Payment Required\r\n"+
							"Content-Type: text/html; charset=utf-8\r\n"+
							"Content-Length: %d\r\n"+
							"Connection: close\r\n"+
							"\r\n"+
							"%s",
						len(response),
						string(response),
					)

					c.Write([]byte(httpResponse))
					log.Printf("📤 已发送付费页面到: %s", c.RemoteAddr().String())
				}
			}(conn)
		}
	}()

	// 等待10秒
	fmt.Println("⏳ 等待10秒用于测试...")
	time.Sleep(10 * time.Second)
	fmt.Println("✅ 演示完成")
}

// min 辅助函数
func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}
